#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

/*
如果是文件夹 入栈
如果是文件  打印
*/

void dir(const char * dir_name);

void dirs(const char * dir_name)
{
    // 打开目录
    DIR * dir_p = opendir(dir_name);
    if (NULL == dir_p)
    {
        ERRLOG("文件夹打开失败");
    }
    
    // 目录内文件结构体
    struct dirent * dit_Stu;

    // 存储目录内的文件名
    char dir_file_name[1024][128];
    int dir_file_len = 0;
    char dir_dir_name[1024][128];
    int dir_dir_len = 0;

    // 遍历 存储 文件名
    while (NULL != (dit_Stu = readdir(dir_p)))
    {
        // 去掉. 和 ..
        if (!strcmp(dit_Stu->d_name , ".") || !strcmp(dit_Stu->d_name , ".."))
        {
            continue;
        }
        //打印所有文件 （文件和文件夹）
        printf("%s\n",dit_Stu->d_name);

        // 将普通文件写入到 dir_file_name 将 目录文件写入到 dir_dir_name

        if (DT_DIR == dit_Stu->d_type) // 将目录存储到目录的顺序表中
        {
            strcpy(dir_dir_name[dir_dir_len] , dit_Stu->d_name);
            dir_dir_len++;
        }
        else// 将 普通文件 存储到 普通文件 的顺序表中
        {
            strcpy(dir_file_name[dir_file_len] , dit_Stu->d_name);
            dir_file_len++;
        }
    }

    // 打印普通文件
    for (size_t i = 0; i < dir_file_len; i++)
    {
        printf("普通文件:%s\n",dir_file_name[i]);
    }
    // 用于组装传入到递归的路径
    char buf_dir_name[1024];
    for (size_t i = 0; i < dir_dir_len; i++)
    {
        // 打印目录文件名
        printf("目录文件:%s\n",dir_dir_name[i]);
        // 组装
        sprintf(buf_dir_name , "./%s%s" , dir_name , dir_dir_name[i]);
        // 打印分割线
        printf("----------------进入到 %s 目录中----------------\n" , buf_dir_name);
        //输出该目录下文件的信息
        dir(buf_dir_name);
        // 
        dirs(buf_dir_name);
        
    }

    closedir(dir_p);

    printf("----------------退出目录----------------\n" );
}



int main(int argc, char const *argv[])
{
    if (2 > argc)
    {
        printf("参数不完整\n");
        return 0;
    }
    
    dirs(argv[1]);
    return 0;
}

void dir(const char * dir_name)
{
    struct stat stat_buf;
    stat(dir_name , &stat_buf);

    // 设备编号
    printf("dev_id = %ld\n" , stat_buf.st_dev);

    // 文件编号  唯一编号
    printf("ino_id = %ld\n" , stat_buf.st_ino);

    // 硬链接的数量
    printf("link_num = %ld\n" , stat_buf.st_nlink);

    // 所占空间大小
    printf("file_size = %ld\n" , stat_buf.st_size);

    // 上次访问时间
    time_t atime = stat_buf.st_atime;
    printf("上次访问时间 = %s" , ctime(&atime));
    // 上次修改时间
    time_t mtime = stat_buf.st_mtime;
    printf("上次修改时间 = %s" , ctime(&mtime));
    // 上次状态改变时间
    time_t Ctime = stat_buf.st_ctime;
    printf("上次状态改变时间 = %s" , ctime(&Ctime));

    //文件所有者的用户
    printf("u_id = %d\n" , stat_buf.st_uid);
    struct passwd * u_struct;
    u_struct = getpwuid(stat_buf.st_uid);
    printf("u_str = %s\n" , u_struct->pw_name);
    //文件所有者的组
    printf("g_id = %d\n" , stat_buf.st_gid);
    struct group * g_struct;
    g_struct = getgrgid(stat_buf.st_gid);
    printf("g_str = %s\n" , g_struct->gr_name);
}
